package com.ailk.tcm.hffw.android.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
 * 
 * @author Administrator
 *
 */
public class BitmapUtil {

	public static int computeSampleSize(BitmapFactory.Options options,
	        int minSideLength, int maxNumOfPixels) {
	    int initialSize = computeInitialSampleSize(options, minSideLength,maxNumOfPixels);

	    int roundedSize;
	    if (initialSize <= 8 ) {
	        roundedSize = 1;
	        while (roundedSize < initialSize) {
	            roundedSize <<= 1;
	        }
	    } else {
	        roundedSize = (initialSize + 7) / 8 * 8;
	    }

	    return roundedSize;
	}

	private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) {
	    double w = options.outWidth;
	    double h = options.outHeight;

	    int lowerBound = (maxNumOfPixels == -1) ? 1 :
	            (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
	    int upperBound = (minSideLength == -1) ? 128 :
	            (int) Math.min(Math.floor(w / minSideLength),
	            Math.floor(h / minSideLength));

	    if (upperBound < lowerBound) {
	        // return the larger one when there is no overlapping zone.
	        return lowerBound;
	    }

	    if ((maxNumOfPixels == -1) &&
	            (minSideLength == -1)) {
	        return 1;
	    } else if (minSideLength == -1) {
	        return lowerBound;
	    } else {
	        return upperBound;
	    }
	}
	
	/**
	 * 通过压缩质量来压缩图片
	 * @param image		原图片
	 * @param aimSize	目标大小，单位kb
	 * @return
	 */
	public static Bitmap compressImageByQuality(Bitmap image, int aimSize) {  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中  
        int options = 100;  
        while ( baos.toByteArray().length / 1024>aimSize) {  //循环判断如果压缩后图片是否大于目标大小,大于继续压缩         
            baos.reset();//重置baos即清空baos  
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中  
            options -= 10;//每次都减少10  
        }  
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中  
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片  
        return bitmap;  
    }
	
	/**
	 * 通过压缩尺寸来压缩图片
	 * @param srcPath	原图片路径
	 * @param width		目标宽度，单位像素，最终会根据宽度和高度中较大的一个进行压缩
	 * @param height	目标高度，单位像素，最终会根据宽度和高度中较大的一个进行压缩
	 * @return
	 */
	public static Bitmap compressImageByResize(String srcPath, int width, int height) {  
        BitmapFactory.Options newOpts = new BitmapFactory.Options();  
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了  
        newOpts.inJustDecodeBounds = true;  
        BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空  
        newOpts.inJustDecodeBounds = false;  
        int w = newOpts.outWidth;  
        int h = newOpts.outHeight;  
        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可  
        int be = 1;//be=1表示不缩放  
        if (w > h && w > width) {//如果宽度大的话根据宽度固定大小缩放  
            be = (int) (newOpts.outWidth / width);  
        } else if (w < h && h > height) {//如果高度高的话根据宽度固定大小缩放  
            be = (int) (newOpts.outHeight / height);  
        }  
        if (be <= 0)  
            be = 1;  
        newOpts.inSampleSize = be;//设置缩放比例  
        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了 
        return BitmapFactory.decodeFile(srcPath, newOpts);  
    }
	
	/**
	 * 通过压缩尺寸来压缩图片
	 * @param image		原图片
	 * @param width		目标宽度，单位像素，最终会根据宽度和高度中较大的一个进行压缩
	 * @param height	目标高度，单位像素，最终会根据宽度和高度中较大的一个进行压缩
	 * @return
	 */
	public static Bitmap compressImageByResize(Bitmap image, int width, int height) {  
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();         
	    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
	    if( baos.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出    
	        baos.reset();//重置baos即清空baos  
	        image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%，把压缩后的数据存放到baos中  
	    }
	    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
	    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
	    //开始读入图片，此时把options.inJustDecodeBounds 设回true了  
	    newOpts.inJustDecodeBounds = true;  
	    BitmapFactory.decodeStream(isBm, null, newOpts);  
	    newOpts.inJustDecodeBounds = false;
	    int w = newOpts.outWidth;  
	    int h = newOpts.outHeight;  
	    //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可  
	    int be = 1;//be=1表示不缩放  
	    if (w > h && w > width) {//如果宽度大的话根据宽度固定大小缩放  
	        be = (int) (newOpts.outWidth / width);  
	    } else if (w < h && h > height) {//如果高度高的话根据宽度固定大小缩放  
	        be = (int) (newOpts.outHeight / height);  
	    }  
	    if (be <= 0)  
	        be = 1;  
	    newOpts.inSampleSize = be;//设置缩放比例  
	    //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了  
	    isBm = new ByteArrayInputStream(baos.toByteArray());
	    return BitmapFactory.decodeStream(isBm, null, newOpts);  
	}  
}
